package com.panopset.io;

import java.io.File;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import com.panopset.Alert;
import com.panopset.compat.Strings;
import com.panopset.UtilIO;
import com.panopset.compat.RezIO;

/**
 * Global replace directory processor.
 *
 * @author Karl Dinwiddie.
 *
 */
public final class GlobalReplace extends DirectoryProcessor {

    /**
     * Drop blanks flag.
     */
    private boolean dropBlanks;

    /**
     *
     * @param value
     *            Blank lines will be dropped during global replace if this is
     *            set to true.
     */
    public void setDropBlanks(final boolean value) {
        dropBlanks = value;
    }

    /**
     * From String.
     */
    private final String from;

    /**
     * To String.
     */
    private final String to;

    /**
     * Extension to limit file types to.
     */
    private final List<String> ext;

    /**
     * @param dir
     *            Directory to traverse.
     * @param fromText
     *            String to replace.
     * @param toText
     *            Replacement String.
     * @param extension
     *            File type to limit processing to, for example
     *            &quot;.txt&quot;. All files will be processed if extension is
     *            null or blank. Comma separated values accepted as well.
     */
    public GlobalReplace(final File dir, final String fromText,
            final String toText, final String extension) {
        super(dir);
        from = fromText;
        to = toText;
        ext = new ArrayList<String>();
        StringTokenizer st = new StringTokenizer(extension, ",");
        while (st.hasMoreElements()) {
            String s = st.nextToken().trim();
            if (s.length() > 0
                && s.indexOf(".") == 0) {
                s = s.substring(1);
            }
            if (s.length() > 0) {
                ext.add("." + s);
            }
        }
    }

    @Override
    protected void process(final File f) {
        if (ext.isEmpty() || ext.contains(UtilIO.getExtension(f))) {
            Alert.green("Processing " + RezIO.getCanonicalPath(f));
            final StringWriter sw = new StringWriter();
            new FileProcessor.Builder()
                    .fileAndListener(f, new FileProcessor.Listener() {

                        @Override
                        public void process(final FileProcessor processor,
                                final String[] values) {
                            for (String s : values) {
                                if (dropBlanks && !Strings.isPopulated(s)) {
                                    continue;
                                }
                                sw.append(s.replace(from, to));
                                sw.append(Strings.getEol());
                            }
                        }

                        @Override
                        public void finish(final FileProcessor processor) {
                            // nothing to do here.
                        }

                    }).construct().exec();
            UtilIO.saveStringToFile(sw.toString(), f);
        }
    }

}
